#include"lexer.hpp"
#include"type.hpp"
#include"explain.hpp"
#include"net.hpp"
#include<iostream>

class ZIS_GC{
	public:
		~ZIS_GC(){
			for(auto &a:pool){
				delete a;
			}
		}
}gc;

int main(int ac,char **av){
	auto help1=[]{
cout<<R"(ZIS is a tool for managing ZIS source code.

Usage:

	zis <command> [args]

The commands are:

	run <source file name> : run a zis program.
	help [full command name] : get helps.
	version : print ZIS version.
	repl : open repl mode.
	net-xxx : the commands of net.
)";
	};
	auto help2=[](const string &str){
		if(str=="help"){
cout<<R"(usage : zis help <command/part>
get helps of a command/part

The commands/parts are:
	help
	run
	version
	repl
	zis (part)
	net (part)
	net-xxx
)";
		}else if(str=="run"){
cout<<R"(usage : zis run <program>
run a zis program
if you wanna know the grammar of zis,
please use `zis help zis`
)";
		}else if(str=="version"){
cout<<R"(usage : zis version
print ZIS version

Formats:
	ZIS-xxx
		xxx is a number of a string such as 1.2.4
)";
		}else if(str=="zis"){
cout<<R"(zis is a pl that is easy to use
you can use `zis help zis` to know the grammar
and you can use `zis net-grammar en` to know the last grammar

print(value) : print a value
	value include string,int,bool,func,slice,char and so on
)";
		}else if(str=="net"){
cout<<R"(`zis net-xxx` is a useful set of commands
The commands are:
	net-version
)";
		}else if(str=="net-version"){
cout<<R"(usage : zis net-version
Get the last ZIS version
)";
		}else if(str=="repl"){
cout<<R"(usage : zis repl
Open REPL mode
)";
		}
		else{
			cout<<"Error : no such command `"<<str<<"`";
		}
	};
	string srcFileName;
	if(ac==1){
//		Words wordObj("test.txt");
//		for(vector<token> &a : wordObj.words){
//			for(token &b : a){
//				cout<<"{"<<b.str<<"} ";
//			}
//			cout<<'\n';
//		}
		help1();
		return 0;
	}
	for(int a=1;a<ac;a++){
		string str(av[a]);
		if(str=="run"){
			srcFileName=av[++a];
		}else if(str=="help"){
			if(a+1<ac){
				help2(av[++a]);
			}else{
				help1();
			}
		}else if(str=="version"){
			cout<<"ZIS version : ZIS-4\n";
		}else if(str=="net-version"){
			cout<<"Last ZIS version : "<<fetch_website("https://gitee.com/jfsoft-studio/zis/raw/master/net/version");
		}else if(str=="repl"){
			cout<<"ZIS REPL\nType 'exit(0)' to get off.\n";
			while(1){
				cin.sync();
				cout<<"\n>>> ";
				string codeLine;
				getline(cin,codeLine);
				ofstream("zis_cache_temp.zis")<<codeLine;
				try{
				Words srcWords("zis_cache_temp.zis");
				int pc=0;
				for(auto &w:srcWords.words){
		//			for(auto &a:w){
		//				cout<<"{"<<a.str<<"} ";
		//			}
					auto vectorSTR=explain(w,pc++);
					cout<<"\nResult : { ";
					for(auto &onarg:vectorSTR){
						if(onarg.str.empty())continue;
						cout<<onarg.str<<" ";
					}
					cout<<"}";
				}
				}catch(const error &a){
					cout<<a.mess<<'\n';
				}
			}
		}
		else{
			srcFileName=str; 
		}
	}
	if(!srcFileName.empty()){
		try{
		Words srcWords(srcFileName);
		int pc=0;
		for(auto &w:srcWords.words){
//			for(auto &a:w){
//				cout<<"{"<<a.str<<"} ";
//			}
			explain(w,pc++);
		}
		}catch(const error &a){
			cout<<a.mess<<'\n';
		}
	}
}